package com.swotxu.ribboninvoker;

import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @Date: 2020/9/19 19:09
 * @Author: swotXu
 */
@Slf4j
@Configuration
@RestController
public class lnvokerController {
    // 服务名 - 服务提供者
    private final String SERVICE_NAME_PROVIDER = "cloud-ribbon-provider";


    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

    @RequestMapping(value = "/router", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public String router(){
        RestTemplate restTemplate = getRestTemplate();
        String json = restTemplate.getForObject(String.format("http://%s/user/1", SERVICE_NAME_PROVIDER), String.class);
        log.info("result: {}", json);
        return json;
    }

    @Autowired
    private LoadBalancerClient loadBalanced;

    @RequestMapping(value = "/uselb", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ServiceInstance uselb(){
        // 查找服务器实例
        ServiceInstance si = loadBalanced.choose(SERVICE_NAME_PROVIDER);
        log.info("ServiceInstance: {}", si);
        return si;
    }

    @Autowired
    private SpringClientFactory factory;

    @RequestMapping(value = "/usefactory", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public String usefactory(){
        log.info("========== 输出 default 配置 ==========");
        printlb(factory.getLoadBalancer("default"));

        log.info("========== 输出 {} 配置 ==========", SERVICE_NAME_PROVIDER);
        printlb(factory.getLoadBalancer(SERVICE_NAME_PROVIDER));

        return "OK!";
    }
    private void printlb(ILoadBalancer lb){
        ZoneAwareLoadBalancer zalb = (ZoneAwareLoadBalancer) lb;

        log.info("ILoadBalancer: {}", lb.getClass().getName());
        log.info("IRule: {}", zalb.getRule().getClass().getName());
        log.info("IPing: {}", zalb.getPing().getClass().getName());
        log.info("PingInterval: {}", zalb.getPingInterval());
        log.info("ClientConfig: {}", zalb.getClientConfig().getClass().getName());
        log.info("ServerListFilter: {}", zalb.getFilter().getClass().getName());
        log.info("ServerListImpl: {}", zalb.getServerListImpl().getClass().getName());
        log.info("ServerListUpdater: {}", zalb.getServerListUpdater().getClass().getName());
    }
}
